home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 2
/
Deutsche Edition 2.iso
/
mac
/
POWERMAC
/
C64
/
SOURCE
/
Memory.c
< prev
next >
Wrap
Text File
|
1994-06-06
|
6KB
|
199 lines
/*
Commodore 64 Emulator v0.4 Earle F. Philhower III
Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Processor.h"
#include "Error.h"
#include "Resources.h"
#include "Memory.h"
/* Global memory pointers */
byte *RAM=nil, *loROM=nil, *hiROM=nil, *charROM=nil;
byte *RAMp1=nil, *loROMp1=nil, *hiROMp1=nil, *charROMp1=nil;
byte **memory=nil, **memoryp1=nil;
/* Used for the memory mapping routines locally */
static byte **loRAMstore=nil, **loROMstore=nil;
static byte **hiRAMstore=nil, **hiROMstore=nil;
static byte **charRAMstore=nil, **charROMstore=nil;
int MemoryInitialize(void)
{
Handle temp;
word x;
/* Get space for RAM and ROMS */
RAM=(byte *)GetMemory(0x10001);
loROM=(byte *)GetMemory(0x2000);
charROM=(byte *)GetMemory(0x1000);
hiROM=(byte *)GetMemory(0x2000);
if ((RAM==nil)||(loROM==nil)||(charROM==nil)||(hiROM==nil))
return(kOutOfMemory);
/* Load the ROMS into the memory allocated */
temp=GetResource('ROMS', kBASICROM); /* BASIC */
if (temp==nil) return(kROMMissing);
BlockMove(*temp, loROM, 0x2000);
ReleaseResource(temp);
temp=GetResource('ROMS', kCHARROM); /* CHARACTERS */
if (temp==nil) return(kROMMissing);
BlockMove(*temp, charROM, 0x1000);
ReleaseResource(temp);
temp=GetResource('ROMS', kKERNELROM); /* KERNAL */
if (temp==nil) return(kROMMissing);
BlockMove(*temp, hiROM, 0x2000);
ReleaseResource(temp);
/* Set up the hi-byte shortcut pointers */
RAMp1=&RAM[1];
loROMp1=&loROM[1];
charROMp1=&charROM[1];
hiROMp1=&hiROM[1];
/* Get the double-dereference memory map space */
memory=(byte**)GetMemory(0x10001*sizeof(byte *));
if (memory!=nil) memoryp1=&(memory[1]);
loRAMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
loROMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
charRAMstore=(byte**)GetMemory(0x1000*sizeof(byte *));
charROMstore=(byte**)GetMemory(0x1000*sizeof(byte *));
hiRAMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
hiROMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
if ((loRAMstore==nil)||(loROMstore==nil)||(charRAMstore==nil)||
(charROMstore==nil)||(hiRAMstore==nil)||(hiROMstore==nil)||
(memory==nil))
return(kOutOfMemory);
/* Set up the standard RAM pointers into our memory[] */
for (x=0x0000; x<0xffff; x++) memory[x]=&RAM[x];
memory[x]=&(RAM[x]); /* Takes care of overflow */
/* Copy the ROM and RAM pointers into our holding places */
for (x=0x0000; x<0x2000; x++) {
loROMstore[x]=&loROM[x];
loRAMstore[x]=&(RAM[0xa000+x]); }
for (x=0x0000; x<0x1000; x++) {
charROMstore[x]=&charROM[x];
charRAMstore[x]=&(RAM[0xd000+x]); }
for (x=0x0000; x<0x2000; x++) {
hiROMstore[x]=&hiROM[x];
hiRAMstore[x]=&(RAM[0xe000+x]); }
return(kNoError);
}
void MemoryCleanUp(void)
{
if (RAM != nil) FreeMemory(RAM);
if (loROM != nil) FreeMemory(loROM);
if (charROM != nil) FreeMemory(charROM);
if (hiROM != nil) FreeMemory(hiROM);
if (memory != nil) FreeMemory(memory);
if (loRAMstore != nil) FreeMemory(loRAMstore);
if (loROMstore != nil) FreeMemory(loROMstore);
if (charRAMstore != nil) FreeMemory(charRAMstore);
if (charROMstore != nil) FreeMemory(charROMstore);
if (hiRAMstore != nil) FreeMemory(hiRAMstore);
if (hiROMstore != nil) FreeMemory(hiROMstore);
}
void SetUpMemoryMap(void)
{
if (*RAMp1&(1<<0)) BlockMove(loROMstore, &memory[0xa000],(0x2000*sizeof(byte *)));
else BlockMove(loRAMstore, &memory[0xa000],(0x2000*sizeof(byte *)));
if (*RAMp1&(1<<1)) BlockMove(charRAMstore, &memory[0xd000],(0x1000*sizeof(byte *)));
else BlockMove(charROMstore, &memory[0xd000],(0x1000*sizeof(byte *)));
if (*RAMp1&(1<<2)) BlockMove(hiROMstore, &memory[0xe000],(0x2000*sizeof(byte *)));
else BlockMove(hiRAMstore, &memory[0xe000],(0x2000*sizeof(byte *)));
CheckMemory();
}
#define SIGNATURE 'BoMb'
#define MAXSLOTS 64
typedef unsigned long SignatureType;
typedef struct {
byte *startOfMem, *givenMemPtr;
SignatureType id;
} Signature;
static Signature signature[MAXSLOTS];
static byte numSignatures=0;
byte *GetMemory(unsigned long size)
{
byte *mem;
/* First see if we've got room in our memory pointers */
if (numSignatures==MAXSLOTS) InternalError(kOutOfMemoryPointers);
/* Get memory from heap, including space for our signature */
mem=(byte *)NewPtrClear(size+sizeof(SignatureType));
if (mem==nil) return (byte *)nil;
/* Set up our memory structure */
signature[numSignatures].startOfMem=mem;
signature[numSignatures].givenMemPtr=&(mem[sizeof(SignatureType)]);
signature[numSignatures].id=SIGNATURE;
/* Store out "sentinel" bytes that SHOULD NOT BE OVERWRITTEN */
BlockMove(&(signature[numSignatures].id), mem, sizeof(SignatureType));
/* Return address just after out sentinel */
return signature[numSignatures++].givenMemPtr;
}
void FreeMemory(void *mem)
{
int x, y;
byte *memory=(byte *)mem;
/* Search for the passed memory pointer in the list of ones we've given */
for (x=0; x<numSignatures; x++)
if (memory==signature[x].givenMemPtr)
{
/* Found a match, free the memory */
DisposePtr((Ptr)signature[x].startOfMem);
/* Shift out pointers down to fill the vacant slot */
for (y=x; y<numSignatures; y++) signature[y]=signature[y+1];
numSignatures--;
return;
}
/* Didn't find the memory, so exit gracefully */
InternalError(kInvalidMemoryFree);
}
void CheckMemory(void)
{
int x;
SignatureType sign;
/* Scan all of out given signatures for the sentinel value */
for (x=0; x<numSignatures; x++)
{
sign=*(SignatureType *)signature[x].startOfMem;
if (sign!=signature[x].id) InternalError(kMemoryViolation);
}
}